using BunnyEater.Common.ResponseOutput;
using BunnyEater.Domain.Base;
using BunnyEater.Domain.Traceable;
using BunnyEater.EntityFrameworkCore;
using BunnyEater.Repository.BaseRepository;
using BunnyEater.Repository.Extensions;
using BunnyEater.Service.TraceableService.FirmService.Dto;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;
using BunnyEater.Common.Enum;

namespace BunnyEater.Service.TraceableService.FirmService
{
    /// <summary>
    /// 企业服务实现，处理企业相关的业务逻辑
    /// </summary>
    public class FirmService : IFirmService
    {
        private readonly BunnyEaterContext _bunnyEaterContext;
        private readonly IRepository<Firm> _firmRepository;
        private readonly ILogger<FirmService> _logger;

        public FirmService(BunnyEaterContext bunnyEaterContext, IRepository<Firm> firmRepository, ILogger<FirmService> logger)
        {
            _bunnyEaterContext = bunnyEaterContext;
            _firmRepository = firmRepository;
            _logger = logger;
        }

        /// <summary>
        /// 分页获取企业列表
        /// </summary>
        /// <param name="query">分页查询参数</param>
        /// <returns>企业分页数据</returns>
        public async Task<ResponseReturnsEntity<Page<FirmListDto>>> GetPagedFirmsAsync(FirmPagedQueryDto query)
        {
            try
            {
                var firms = _firmRepository.GetListQuery().Where(f => !f.IsDelete);
                if (!string.IsNullOrEmpty(query.FirmName))
                {
                    firms = firms.Where(f => EF.Functions.Like(f.FirmName, $"%{query.FirmName}%"));
                }
                if (query.FirmType.HasValue)
                {
                    firms = firms.Where(f => f.FirmType == query.FirmType.Value);
                }
                var result = await firms.ToPagedListAsync(
                    query.PageIndex,
                    query.PageSize,
                    null,
                    f => f.CreateTime,
                    false);
                var dtoPage = new Page<FirmListDto>
                {
                    Items = result.Items.Select(f => new FirmListDto
                    {
                        Id = f.Id,
                        FirmName = f.FirmName,
                        FirmType = f.FirmType,
                        Farms = f.Farms,
                        Head = f.Head,
                        FarmsNum = f.FarmsNum,
                        Province = f.Province,
                        City = f.City,
                        District = f.District,
                        Address = f.Address,
                        Brief = f.Brief,
                        LicenseNo = f.LicenseNo,
                        CreateTime = f.CreateTime
                    }).ToList(),
                    PageNumber = result.PageNumber,
                    PageSize = result.PageSize,
                    TotalPages = result.TotalPages,
                    TotalItems = result.TotalItems
                };
                return ResponseReturnsEntity<Page<FirmListDto>>.Success(dtoPage);
            }
            catch (Exception ex)
            {
                _logger.LogError($"分页查询企业失败: {ex.Message}");
                return ResponseReturnsEntity<Page<FirmListDto>>.Fail($"查询失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 新增企业，包含事务处理和异常回滚
        /// </summary>
        /// <param name="dto">企业信息</param>
        /// <returns>操作结果</returns>
        /// <remarks>
        /// 1. 自动为主键Id赋值Guid字符串。
        /// 2. 包含事务处理，失败自动回滚。
        /// 3. 捕获数据库异常和通用异常，记录详细日志。
        /// </remarks>
        public async Task<ResponseReturnsEntity<bool>> AddFirm(FirmListDto dto)
        {
            using var transaction = await _bunnyEaterContext.Database.BeginTransactionAsync();
            try
            {
                // 参数校验
                if (dto == null)
                {
                    return ResponseReturnsEntity<bool>.Fail("企业信息不能为空");
                }
                if (string.IsNullOrEmpty(dto.FirmName))
                {
                    return ResponseReturnsEntity<bool>.Fail("企业名称不能为空");
                }

                var entity = new Firm
                {
                    Id = Guid.NewGuid().ToString(),
                    FirmName = dto.FirmName,
                    FirmType = dto.FirmType,
                    Farms = dto.Farms,
                    Head = dto.Head,
                    FarmsNum = dto.FarmsNum,
                    Province = dto.Province,
                    City = dto.City,
                    District = dto.District,
                    Address = dto.Address,
                    Brief = dto.Brief,
                    LicenseNo = dto.LicenseNo,
                    CreateTime = DateTime.Now
                };
                var result = await _firmRepository.InsertEntityAsync(entity);

                await transaction.CommitAsync();
                return ResponseReturnsEntity<bool>.Success(result > 0);
            }
            catch (DbUpdateException dbEx)
            {
                await transaction.RollbackAsync();
                _logger.LogError($"数据库更新异常，添加企业失败: {dbEx.Message}", dbEx);
                return ResponseReturnsEntity<bool>.Fail("数据库操作异常，添加企业失败，请检查数据有效性或联系管理员。");
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync();
                _logger.LogError($"添加企业失败: {ex.Message}", ex);
                return ResponseReturnsEntity<bool>.Fail($"添加企业失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新企业信息，包含异常处理
        /// </summary>
        /// <param name="dto">企业信息</param>
        /// <returns>操作结果</returns>
        /// <remarks>
        /// 1. 包含参数校验和存在性检查。
        /// 2. 捕获数据库异常和通用异常，记录详细日志。
        /// </remarks>
        public async Task<ResponseReturnsEntity<bool>> UptFirm(FirmListDto dto)
        {
            try
            {
                // 参数校验
                if (dto == null)
                {
                    return ResponseReturnsEntity<bool>.Fail("企业信息不能为空");
                }
                if (string.IsNullOrEmpty(dto.Id))
                {
                    return ResponseReturnsEntity<bool>.Fail("企业ID不能为空");
                }
                if (string.IsNullOrEmpty(dto.FirmName))
                {
                    return ResponseReturnsEntity<bool>.Fail("企业名称不能为空");
                }

                var entity = await _firmRepository.GetEntityByIdAsync(new Firm { Id = dto.Id });
                if (entity == null)
                {
                    return ResponseReturnsEntity<bool>.Fail("企业不存在");
                }

                entity.FirmName = dto.FirmName;
                entity.FirmType = dto.FirmType;
                entity.Farms = dto.Farms;
                entity.Head = dto.Head;
                entity.FarmsNum = dto.FarmsNum;
                entity.Province = dto.Province;
                entity.City = dto.City;
                entity.District = dto.District;
                entity.Address = dto.Address;
                entity.Brief = dto.Brief;
                entity.LicenseNo = dto.LicenseNo;
                entity.ModifyTime = DateTime.Now;

                var result = await _firmRepository.UpdateEntityAsync(entity);
                return ResponseReturnsEntity<bool>.Success(result > 0);
            }
            catch (DbUpdateException dbEx)
            {
                _logger.LogError($"数据库更新异常，更新企业失败: {dbEx.Message}", dbEx);
                return ResponseReturnsEntity<bool>.Fail("数据库操作异常，更新企业失败，请检查数据有效性或联系管理员。");
            }
            catch (Exception ex)
            {
                _logger.LogError($"更新企业失败: {ex.Message}", ex);
                return ResponseReturnsEntity<bool>.Fail($"更新企业失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 删除企业（逻辑删除），包含异常处理
        /// </summary>
        /// <param name="id">企业Id</param>
        /// <returns>操作结果</returns>
        /// <remarks>
        /// 1. 包含参数校验和存在性检查。
        /// 2. 捕获数据库异常和通用异常，记录详细日志。
        /// </remarks>
        public async Task<ResponseReturnsEntity<bool>> DeleteFirm(string id)
        {
            try
            {
                // 参数校验
                if (string.IsNullOrEmpty(id))
                {
                    return ResponseReturnsEntity<bool>.Fail("企业ID不能为空");
                }

                var entity = await _firmRepository.GetEntityByIdAsync(new Firm { Id = id });
                if (entity == null)
                {
                    return ResponseReturnsEntity<bool>.Fail("企业不存在");
                }

                if (entity.IsDelete)
                {
                    return ResponseReturnsEntity<bool>.Fail("企业已被删除，请勿重复操作");
                }

                entity.IsDelete = true;
                entity.ModifyTime = DateTime.Now;

                var result = await _firmRepository.UpdateEntityAsync(entity);
                return ResponseReturnsEntity<bool>.Success(result > 0);
            }
            catch (DbUpdateException dbEx)
            {
                _logger.LogError($"数据库更新异常，删除企业失败: {dbEx.Message}", dbEx);
                return ResponseReturnsEntity<bool>.Fail("数据库操作异常，删除企业失败，请检查数据有效性或联系管理员。");
            }
            catch (Exception ex)
            {
                _logger.LogError($"删除企业失败: {ex.Message}", ex);
                return ResponseReturnsEntity<bool>.Fail($"删除企业失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 根据Id获取企业信息
        /// </summary>
        /// <param name="id">企业Id</param>
        /// <returns>企业信息</returns>
        public async Task<ResponseReturnsEntity<FirmListDto>> GetFirmById(string id)
        {
            var entity = await _firmRepository.GetEntityByIdAsync(new Firm { Id = id });
            if (entity == null) return ResponseReturnsEntity<FirmListDto>.Fail("企业不存在");
            var dto = new FirmListDto
            {
                Id = entity.Id,
                FirmName = entity.FirmName,
                FirmType = entity.FirmType,
                Farms = entity.Farms,
                Head = entity.Head,
                FarmsNum = entity.FarmsNum,
                Province = entity.Province,
                City = entity.City,
                District = entity.District,
                Address = entity.Address,
                Brief = entity.Brief,
                LicenseNo = entity.LicenseNo,
                CreateTime = entity.CreateTime
            };
            return ResponseReturnsEntity<FirmListDto>.Success(dto);
        }
    }
}